﻿Namespace EIBData
    Public NotInheritable Class EIBDataContainer

        Private _data As Byte()

        Private _isDecoded As Enums.EIBData_DecodationState = Enums.EIBData_DecodationState.Undecoded
        Private _decodedData_EIS As EIS.EIBDataEIS_Base = Nothing
        Private _decodedData_DPT As DPT.EIBDataDPT_Base = Nothing


        Sub New(data As Byte())
            _data = data

            _decodedData_EIS = Nothing
            _decodedData_DPT = Nothing
            _isDecoded = Enums.EIBData_DecodationState.Undecoded
        End Sub

        Sub New(data As Byte(), type As Type)
            _data = data

            If type.IsSubclassOf(GetType(EIS.EIBDataEIS_Base)) Then
                TryDecodeAsEIS(type)
            ElseIf type.IsSubclassOf(GetType(DPT.EIBDataDPT_Base)) Then
                TryDecodeAsDPT(type)
            End If
        End Sub

        Sub New(data As Byte(), type1 As Type, type2 As Type)
            _data = data

            If type1.IsSubclassOf(GetType(EIS.EIBDataEIS_Base)) Then
                TryDecodeAsEIS(type1)
            ElseIf type1.IsSubclassOf(GetType(DPT.EIBDataDPT_Base)) Then
                TryDecodeAsDPT(type1)
            End If

            If type2.IsSubclassOf(GetType(EIS.EIBDataEIS_Base)) Then
                TryDecodeAsEIS(type2)
            ElseIf type2.IsSubclassOf(GetType(DPT.EIBDataDPT_Base)) Then
                TryDecodeAsDPT(type2)
            End If
        End Sub

        Sub New(value As EIS.EIBDataEIS_Base)
            _data = value.ToByte

            _decodedData_EIS = value
            _decodedData_DPT = Nothing
            _isDecoded = Enums.EIBData_DecodationState.Decoded_EIS
        End Sub

        Sub New(value As DPT.EIBDataDPT_Base)
            _data = value.ToByte

            _decodedData_EIS = Nothing
            _decodedData_DPT = value
            _isDecoded = Enums.EIBData_DecodationState.Decoded_DPT
        End Sub


        Public ReadOnly Property Data As Byte()
            Get
                Return _data
            End Get
        End Property

        Public ReadOnly Property IsDecoded As Enums.EIBData_DecodationState
            Get
                Return _isDecoded
            End Get
        End Property

        Public ReadOnly Property DecodedData_EIS As EIS.EIBDataEIS_Base
            Get
                Return If(_isDecoded And Enums.EIBData_DecodationState.Decoded_EIS, _decodedData_EIS, Nothing)
            End Get
        End Property

        Public ReadOnly Property DecodedData_DPT As DPT.EIBDataDPT_Base
            Get
                Return If(_isDecoded And Enums.EIBData_DecodationState.Decoded_DPT, _decodedData_DPT, Nothing)
            End Get
        End Property


        Public Sub TryDecodeAs(type As EIB.Managers.EIBDataTypeManger)
            If type.EISType IsNot Nothing Then TryDecodeAsEIS(type.EISType.GetType)
            If type.DPTType IsNot Nothing Then TryDecodeAsDPT(type.DPTType.GetType)
        End Sub

        Public Function TryDecodeAsEIS(type As Type) As Boolean
            If _isDecoded And Enums.EIBData_DecodationState.Decoded_EIS AndAlso type = _decodedData_EIS.GetType Then Return True

            Try
                _decodedData_EIS = DecodeAsEIS(type)
                _isDecoded = If(_isDecoded And Enums.EIBData_DecodationState.Decoded_DPT, Enums.EIBData_DecodationState.Decoded_Both, Enums.EIBData_DecodationState.Decoded_EIS)
                Return True
            Catch ex As EIB.Exceptions.EIBDataDecodeException
                _decodedData_EIS = Nothing
                _isDecoded = If(_isDecoded And Enums.EIBData_DecodationState.Decoded_DPT, Enums.EIBData_DecodationState.Decoded_DPT, Enums.EIBData_DecodationState.Undecoded)
                Return False
            End Try
        End Function

        Private Function DecodeAsEIS(type As Type) As EIS.EIBDataEIS_Base
            Return Activator.CreateInstance(type, _data)
        End Function

        Public Function TryDecodeAsDPT(type As Type) As Boolean
            If _isDecoded And Enums.EIBData_DecodationState.Decoded_DPT AndAlso type = _decodedData_DPT.GetType Then Return True

            Try
                _decodedData_DPT = DecodeAsDPT(type)
                _isDecoded = If(_isDecoded And Enums.EIBData_DecodationState.Decoded_EIS, Enums.EIBData_DecodationState.Decoded_Both, Enums.EIBData_DecodationState.Decoded_DPT)
                Return True
            Catch ex As Exception
                _decodedData_DPT = Nothing
                _isDecoded = If(_isDecoded And Enums.EIBData_DecodationState.Decoded_EIS, Enums.EIBData_DecodationState.Decoded_EIS, Enums.EIBData_DecodationState.Undecoded)
                Return False
            End Try
        End Function

        Private Function DecodeAsDPT(type As Type) As DPT.EIBDataDPT_Base
            Return Activator.CreateInstance(type, _data)
        End Function
    End Class
End Namespace